//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <ddk.h>

#define THREADAMOUNT        100

Int32     g_nszThread[THREADAMOUNT];

Int32 GetMyselfId(void *pvPara)
{
    ThreadState     thdState;
    IThread         *pIThread;
    ECode           ec;
    Int32           nThdId;

    ec = DzGetCurrentThread(&pIThread);
    assert(NOERROR == ec);

    ec = pIThread->GetId(&nThdId);
    assert(NOERROR == ec);

    if (0 == g_nszThread[(uint_t)pvPara]) {
        g_nszThread[(uint_t)pvPara] = nThdId;
    }
    else {
        assert(g_nszThread[(uint_t)pvPara] == nThdId);
    }

    ec = pIThread->GetState(&thdState);
    assert(NOERROR == ec);
    assert(ThreadState_Running == thdState);

    pIThread->Release();

    return NOERROR;
}

EXTERN void ThreadGetId()
{
    IThread     *pIThread[THREADAMOUNT];
    Int32         nThreadId;
    ECode     ec;
    uint_t      i;

    for (i = 0; i < THREADAMOUNT; i++) {
        g_nszThread[i] = 0;
    }

    for (i = 0; i < THREADAMOUNT; i++) {
        ec = DzCreateKernelThread(GetMyselfId, (void *)i, 0,
                        (ThreadPriorityRank)0xFFFFEEEE, &pIThread[i]);
        if (FAILED(ec)) {
            kprintf("Create thread %d failed, the ec = 0x%08x\n", i, ec);
            assert(0);

            return;
        }
    }

    for (i = 0; i < THREADAMOUNT; i++) {
        ec = pIThread[i]->GetId(NULL);
        assert(E_INVALID_ARGUMENT == ec);
    }

    for (i = 0; i < THREADAMOUNT; i++) {
        ec = pIThread[i]->GetId(&nThreadId);
        assert(NOERROR == ec);

        if (0 == g_nszThread[i]) {
            g_nszThread[i] = nThreadId;
        }
        else {
            assert(g_nszThread[i] == nThreadId);
        }
    }

    for (i = 0; i < THREADAMOUNT; i++) {
        ec = pIThread[i]->Join(INFINITE);
        assert(NOERROR == ec);
    }

    for (i = 0; i < THREADAMOUNT; i++) {
        ec = pIThread[i]->GetId(&nThreadId);
        assert(NOERROR == ec);
        assert(g_nszThread[i] == nThreadId);
    }

    for (i = 0; i < THREADAMOUNT; i++) {
        pIThread[i]->Release();
    }
}
